/*
 * Copyright 2008 Mark Davidson.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */

package org.doofer.test

import org.doofer.*
import com.documentum.fc.client.*
import com.documentum.com.*

/**
 * Tests for QueryUtil
 */
class QueryUtilTest extends DooferBaseTest {

    final def listCabinetsDql = 'select object_name from dm_cabinet order by object_name'
    final def qu = new QueryUtil()
    def su = null
    def params = null

    def updateFolderDql
    def deleteFolderDql
    def createFolderDql
    def selectFolderDql

    void setUp() {
        super.setUp()
        params = [username: username, password: password, repository: repository]
        su = new SessionUtil(params)
    }

    void testToList() {
        println "testing toList()"
        def dql =
        """
        select r_object_id, object_name
        from dm_cabinet
        where object_name = 'Templates'
        or object_name = 'System'
        order by object_name, r_object_id
        """

        def results = null
        def failed = false

        try {
            su.useSession { session ->
                results = qu.toList(session: session, dql: dql)
            }
        } catch (Throwable t) {
            println "Detected error: $t.message"
            failed = true
        }

        assertFalse(failed)
        assert(results)
        assertEquals(2, results.size())
        assertEquals('System', results[0].object_name)
        assertEquals('Templates', results[1].object_name)
    }

    void testWalk() {
        println "testing walk()"
        def containers = ['AcsConfig', 'Applications', 'DataDictionary', 'Methods', 'Modules', 'TBO', 'SBO']
        def objects = ['MenuSystem.ini', 'FormatPreferences.ini']
        def failed = false
        def matchedContainers = []
        def matchedObjects = []
        
        try {
            su.useSession { session ->
                qu.walk(session: session, path: '/System', recursive: true) { attribs ->
                    //println "got object: $attribs"
                    if(containers.contains(attribs.object_name)) matchedContainers << attribs.object_name
                    else if(objects.contains(attribs.object_name)) matchedObjects << attribs.object_name
                }
            }
        } catch(Throwable t) {
            println "Detected error: $t.message"
            failed = true
        }

        assertFalse(failed)
        //println "matchedContainers = $matchedContainers"
        //println "matchedObjects = $matchedObjects"
        assertEquals(containers.size(), matchedContainers.size())
        assertEquals(objects.size(), matchedObjects.size())
    }

    void testQuery() {
        println "testing query()"
        updateFolderDql = "update dm_folder object set title = 'updated' where object_name = 'Doofer' and folder('/$username')"
        deleteFolderDql = "delete dm_folder object where object_name = 'Doofer' and folder('/$username')"
        createFolderDql = "create dm_folder object set object_name = 'Doofer' link '/$username'"
        selectFolderDql = "select object_name, title from dm_folder where object_name = 'Doofer' and folder('/$username')"

        def failed = false

        try {
            su.useSession { session ->
                query(session: session, query: buildQuery())
                query(session: session, dql: listCabinetsDql)
                query(session: session, dql: listCabinetsDql, queryType: IDfQuery.DF_READ_QUERY)
                query(session: session, dql: listCabinetsDql, queryType: IDfQuery.DF_EXEC_QUERY)
                exec(session: session, queryType: IDfQuery.DF_EXEC_QUERY)
                exec(session: session)
            }
        } catch (Throwable t) {
            println "Detected error: $t.message"
            failed = true
        }

        assertFalse(failed)
    }

    def buildQuery() {
        def query = clientX.query
        query.DQL = listCabinetsDql
        query
    }
    
    void query(Map params) {
        def cabinets = []
        qu.execute(params) { row ->
            cabinets << row.getString('object_name')
        }
        assert(cabinets)
        assert(cabinets.contains('System'))
    }

    def folderExists(params) {
        def folderExists = false
        qu.execute(params + [dql: selectFolderDql]) { row ->
            folderExists = true
        }
        folderExists
    }

    def checkFolderTitle(params) {
        def title
        qu.execute(params + [dql: selectFolderDql]) { row ->
            title = row.getString('title')
        }
        title
    }

    void exec(Map params) {
        qu.execute(params + [dql: deleteFolderDql])
        assertFalse(folderExists(params))

        qu.execute(params + [dql: createFolderDql])
        assertTrue(folderExists(params))

        qu.execute(params + [dql: updateFolderDql])
        assertEquals('updated', checkFolderTitle(params))

        qu.execute(params + [dql: deleteFolderDql])
        assertFalse(folderExists(params))
    }
}